const fs = require('fs');
const path = require('path');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const babel = require('@babel/core');

//入口分析
const entryAnlyzer = function(entry){

    let rootFolder = path.dirname(entry);
    
    const mainContent = fs.readFileSync(entry,'utf-8');

    const ast = parser.parse(mainContent,{
        sourceType:'module'
    });

    let depMap = {};
    

    traverse(ast,{
        ImportDeclaration({node}){
            
            depMap[node.source.value] =  './' +  path.join(rootFolder,node.source.value).replace('\\','/');
            //depMap[node.source.value] =  rootFolder + node.source.value.substring(1);

        }
    })
    


    const { code } = babel.transformFromAst(ast,null,{
        presets:[
            '@babel/preset-env'
        ]
    });

    return {
        depMap,
        code,
        entry
    }
    

}

//依赖分析
const depAnlyzer = function(entry){
    let entryInfo = entryAnlyzer(entry);
    let depArr = [entryInfo];
    for(let i = 0; i < depArr.length; i++){
        let item = depArr[i];
        if(item.depMap){
            for(let per in item.depMap){
                depArr.push(entryAnlyzer(item.depMap[per]));
            }
        }
    }

    
    let jsonData = {};
    depArr.forEach(item=>{
        jsonData[item.entry] = {
            code:item.code,
            depMap:item.depMap
        }
    });

    return jsonData;
    
}


const genCode = (entry) => {
    console.log(depAnlyzer(entry));
    let graph = JSON.stringify(depAnlyzer(entry));
    return `

        (function(graph){

            
            function require(module){
                function localRequire(relativePath){
                    return require(graph[module].depMap[relativePath]);
                }
                var exports = {};
                (function(require,exports,code){

                    eval(code);
                })(localRequire,exports,graph[module].code)

                return exports;

            }

            require("${entry}")

        })(${graph})
    
    `;
}

let code = genCode('./src/main.js');

fs.writeFileSync('./dist/main.bundle.js',code);